#include "projectHeader.h" 

void processGet()
{
				char getFileUOID[21];
				char getFileMetadata[MAXFILEBUF];
				memset(&getFileUOID[0],'\0',21);
				memset(&getFileMetadata[0],'\0',MAXFILEBUF);
				
				
				// Search the query in search command results.
				pthread_mutex_lock(&indexMutex);
			//	printf("------------2-------------%d\n",indexSearchResponseMap.size());
				bool foundOnMyNodeSoDoNotflood=false;
				if(indexSearchResponseMap.size() != 0 )
				{
					map<int,searchResponseInfo>:: iterator searchIt;
					for(searchIt=indexSearchResponseMap.begin();searchIt != indexSearchResponseMap.end();searchIt++)
					{
						memset(&getFileUOID[0],'\0',21);
						if((*searchIt).first == getFileNumber)
						{
			//				printf("Compare in processGet() : %d ---> %d\n",(*searchIt).first,getFileNumber);
							memcpy(&getFileUOID[0],((*searchIt).second).fileID,20);
							printUOID((unsigned char*)getFileUOID);
							if(((*searchIt).second).isOrigin)
							{
								foundOnMyNodeSoDoNotflood=true;
								break;
							}
							else
							{
								foundOnMyNodeSoDoNotflood=false;
								memcpy(&getFileMetadata[0],&(((*searchIt).second).fileMetaBuffer[0]),MAXFILEBUF);
								break;
							}
						}
					}
				}
				else
				{
					printf("No Result found in search command.\n");
					pthread_mutex_unlock(&indexMutex);	
					return;
					
				}
				pthread_mutex_unlock(&indexMutex);		

				if(foundOnMyNodeSoDoNotflood)  /// the search result wanted is on current node so no need to flood the request.
				{
					pthread_mutex_lock(&indexMutex);
					list<indexFileMetaInfo>:: iterator flistIt;

					for(flistIt=indexFileMetaInfoList.begin();flistIt!=indexFileMetaInfoList.end();flistIt++)
					{
						if(!(strncmp((char*)(*flistIt).fileID,(char*)getFileUOID,20)))
						{
							//remove from cache is file is part of Cache space
							if((*flistIt).isInCache)
							{
								(*flistIt).isInCache=false;
								remainingCacheSizeInBytes+=(*flistIt).filesize;
							}


							//if new file name is not specified then set filename same as in list
							if(!getFileNameSpcified)
							{
								memset(&getFileName[0],'\0',512);
								memcpy(&getFileName[0], &(*flistIt).originalFileName[0],256);
							}
							// check if the file already exit. If it does ask for the user conformation to overrite.
							bool fileExist=false;
							struct stat s;
							if(stat(getFileName,&s) == -1){
								//printf("Invalid Path name\n");
								fileExist=false;
							}
						/*	if (S_ISREG(s.st_mode)) // check whether file is reggular file or not. 
							{
							  fileExist=true;
							}
						*/	
							if(fileExist)
							{
								char overwrite[5];
								printf("File already exist. Do you want to overwrite(y/Y for YES. Anything else for NO)\n");
								/*struct timeval tv;
								fd_set readfds;

								tv.tv_sec = 2;
								tv.tv_usec = 500000;

								FD_ZERO(&readfds);
								FD_SET(0, &readfds);

								// don't care about writefds and exceptfds:
								select(1, &readfds, NULL, NULL, &tv);

								if (FD_ISSET(0, &readfds))
									printf("A key was pressed!\n");
								else
									printf("Timed out.\n");*/
								scanf("%s",overwrite);
								printf("\n");

								if (  (overwrite[0] != 'y') || (overwrite[0] != 'Y'))
								{
				
									printf("File not replaced\n");
									break;
								}

							}

							// Copy content of .data into filename in getFileName.
							char newNumDataFile[256];
							
							memset(newNumDataFile, '\0', 256);
							memcpy(newNumDataFile,homeDir,strlen(homeDir));
							strcat(newNumDataFile,"/files");
							char appendDFileName[256];
							sprintf(appendDFileName, "/%d.data", (*flistIt).numFileName);
							strcat(newNumDataFile,appendDFileName);
							
							FILE *fDataRead = fopen(newNumDataFile,"r");
							FILE *wGetFile = fopen(getFileName,"w");

							int remainingDataToBeCopied = (*flistIt).filesize;
							int numberOfSegments = ceil((double)remainingDataToBeCopied/MAXFILEBUF);	
							 char copyBuf[MAXFILEBUF];
							 memset(&copyBuf[0],'\0',MAXFILEBUF);
							for(int k=0;k<numberOfSegments;k++)
							{
								int bytestoread;
								if (remainingDataToBeCopied > MAXFILEBUF)
								{
									bytestoread = MAXFILEBUF;
									remainingDataToBeCopied = remainingDataToBeCopied - MAXFILEBUF;
								}
								else
									bytestoread = remainingDataToBeCopied;

								memset(&copyBuf[0],'\0',MAXFILEBUF);
								if (fread(copyBuf,1,bytestoread,fDataRead) < 0)
								{
									printf("Error in reading data file\n");
								}
								fwrite(copyBuf, 1, bytestoread, wGetFile);	
							}
							fclose(fDataRead);
							fclose(wGetFile);
					//		printf("File on my node only. Written successfully in current directory.\n");
							break;





						}
					}//end of for

				pthread_mutex_unlock(&indexMutex);

				}
				else			// Result file requested is on some other node.
				{
				//	printf("Ready to flood...\n");
					
					// Populate the GETREQ and flood the msg.
					// Extract the SHA1 from the File Meta data saved. Logic for parsing already done.. REuse the logic. SHA will come in ptrTagValue[2]
							char *ptrTag[10];
							int tagId=0;
							char *ptrTagValue[10];
							int tagValueId=0;
							//printf("File Meta Data is \n%s\n",getFileMetadata);
							for (int i = 0; i<7 ; i++)
							{
								if (i == 0)
								{
									ptrTag[tagId] = strtok((char*)getFileMetadata, "\n");
									
									//printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
								}
								else
								{
									ptrTag[tagId] = strtok((char*)NULL, "=");
									
									//printf("MetaTag-%d : [%s]\n", tagId, ptrTag[tagId]);
									tagId++;
									ptrTagValue[tagValueId] = strtok((char*)NULL, "\n");
									
									//printf("MetaTagValue-%d : [%s]\n", tagValueId, ptrTagValue[tagValueId]);
									tagValueId++;
								}
							}
						
						// convert 40byte SHA1 to 20Byte SHA1 for populating in get req packet.

						unsigned char oldSHA1[41];
						unsigned char newSHA1[21];
						memset(&oldSHA1[0],'\0',41);
						memcpy(&oldSHA1[0],ptrTagValue[2],40);
						
						for (int i = 0; i<40 ; i++)
						{
							int j = i/2;
							unsigned char convertedChar = charHexLookupConverter(oldSHA1[i]);
							if (i%2 == 0)
							{
								newSHA1[j] = newSHA1[j] | convertedChar<<4;
							}
							else
							{
								newSHA1[j] = newSHA1[j] | convertedChar;
							}
						}





						// Populate the GET REQ header.
							msgHeaderClass  getReqHeader;
							unsigned char *buff1;
							char* msg = (char*)"GTRQ";

							//printf("NON BEACON ACCEPT : NodeID is %s\n",nodeInstanceId);
							getReqHeader.messageType=0xDC;
							buff1=GetUOID((char *)nodeInstanceId,msg,buf, sizeof(buf));
							memcpy(getReqHeader.UOID,buf,20);
							getReqHeader.ttlInHeader=ttl;
							getReqHeader.msgDataLength=40;
							
							

							queueItem msgToBePushed;
							msgToBePushed.msgHeader.messageType=getReqHeader.messageType;
							memcpy(msgToBePushed.msgHeader.UOID,getReqHeader.UOID,20);
							msgToBePushed.msgHeader.ttlInHeader=getReqHeader.ttlInHeader;	
							

							msgToBePushed.msgHeader.msgDataLength=getReqHeader.msgDataLength;
							//Copy Data from itemfromqueue into new quueue item.
							memcpy(&(msgToBePushed.dataBuf[0]),&(getFileUOID[0]),20);
							
							memcpy(&(msgToBePushed.dataBuf[20]),&(newSHA1[0]),20);
							
							/*pthread_mutex_lock(&UOIDMsgLifeTimeMapMutex);
							unsigned char uoidToInsertInMap[20];
							memcpy(&uoidToInsertInMap[0],getReqHeader.UOID,20);
							string uoid((const char*)uoidToInsertInMap,20);
							msgLifeTimeClass newEntry(-1,msgLifeTime);
							//newEntry.sockOfMsgReciept=itemFromQueue.sockfd;
							//newEntry.msgLifeTimeValue=msgLifeTime;
							UOIDMsgLifeTimeMap.insert(pair<string,msgLifeTimeClass>(uoid,newEntry));

							pthread_mutex_unlock(&UOIDMsgLifeTimeMapMutex);

							map<string,int>::iterator conNodeListIterator;
							for ( conNodeListIterator=connectedNodeList.begin() ; conNodeListIterator != connectedNodeList.end(); conNodeListIterator++ )
							{
									

											int socket=(*conNodeListIterator).second;
											printf("---------------5--------------%d\n",socket);
												//printf("---------------6--------------\n");
												pthread_mutex_lock(&sockIndexMapMutex);
												int index=sockFDToQIndexMap[socket];
													pthread_mutex_lock(&wrtieQMutex[index]);
														printf("GET PROCESS THREAD: Will push %s data in queue.\n\n",msgToBePushed.dataBuf);
														wrtieThreadQueue[index].push_back(msgToBePushed);
														printf("GET PROCESS THREAD: GET REQ MSG: Msg pushed to writeQueue of %d\n",index);
														pthread_cond_broadcast(&wrtieQCV[index]);

													pthread_mutex_unlock(&wrtieQMutex[index]);								
												pthread_mutex_unlock(&sockIndexMapMutex);
							}
							*/						

							pthread_mutex_lock(&eventQueueMutex);
					
								
								eventQueue.push_back(msgToBePushed);
								//printf("Read Thread:MSG Pushed to Event Dispatcher.\n");
								pthread_cond_broadcast(&eventQueueCV);

							pthread_mutex_unlock(&eventQueueMutex);

				}

				return;
	
}


